<?php

/**
 * 自定义常量
 * User: Ryan
 */

define('MAIN_DOMAIN', 'mlwssc.top');

/**
 * 模板函数开始
 * User: Ryan
 */

// 判断用户是否登录 否则返回异常
function checkUserSession()
{
    if (session('uid') == false) throw new \think\Exception('请先登录');
}
// 获取导航
function getNavTree($parent_id = 0)
{
    return \app\common\model\Nav::getTree($parent_id);
}
function getNavCrumbs($gid = 0)
{
    return \app\common\model\Nav::getCrumbs($gid);
}
function getNavByGid($gid, $show_tree = true)
{
    if($show_tree)
        $list = \app\common\model\Nav::getTreeByGid($gid);
    else
        $list = \app\common\model\Nav::where('parent_id', \app\common\model\Nav::getIdByGid($gid))->select();
    return $list;
}
function postUrl($flag)
{
    return '?act=' . $flag;
}
function getCurrentPath()
{
    return cookie('current_path');
}

function getArticleCategoryByNavGid($gid)
{
    $nav_id = \app\common\model\Nav::getIdByGid($gid);
    return \app\common\model\ArticleCategory::getListByNavId($nav_id);
}
// 获取单个
function getArticleByGid($gid)
{
    return \app\common\model\Article::where('gid', $gid)->find();
}
function getArticleById($id)
{
    $data = \app\common\model\Article::where('id', $id)->find();
    $data['pre_id'] = \app\common\model\Article::where('id', '<', $id)->order('is_top desc, is_recommend desc,id')->value('id');
    $data['next_id'] = \app\common\model\Article::where('id', '>', $id)->order('is_top desc, is_recommend desc,id')->value('id');
    return $data;
}

function getArticlesByCategoryId($id, $nav_gid, $per_page=20)
{
    $cate_id = $id;
    if($id == 0) {
        $cate_id = \app\common\model\ArticleCategory::getFirstByNavGid($nav_gid);
    }
    $category_ids = \app\common\model\ArticleCategory::getChildIds($cate_id);
    return \app\common\model\Article::where('category_id', 'in', $category_ids)->paginate($per_page);
}
// 获取文章列表
// $nav_gid 导航的gid
function getArticlesByNavGid($nav_gid, $where='', $limit=20)
{
    $category_ids = \app\common\model\ArticleCategory::getIdsByNavGid($nav_gid);
    return \app\common\model\Article::where($where)->where('category_id', 'in', $category_ids)->limit($limit)
        ->order('sort desc')->field('id,title,subtitle,summary,category_id,image')->paginate(20);
}
function getArticlesByNavId($nav_id, $where='', $limit=20)
{
    $category_ids = \app\common\model\ArticleCategory::getIdsByNavGid($nav_id);
    return \app\common\model\Article::where($where)->where('category_id', 'in', $category_ids)->limit($limit)
        ->order('sort desc')->field('id,title,subtitle,summary,category_id,image')->paginate(20);
}
// 获取广告
function getAdByGid($gid)
{
    return \app\common\model\Advertisement::where('gid', $gid)->order('sort desc')->select();
}
// 获取单个广告 可以加索引
function getAdOneByGid($gid, $index = 0)
{
    $ad = getAdsByGid($gid);
    return empty($ad) ? [] : $ad[$index];
}
// 获取产品列表
function getProductList($where = '')
{
    return \app\common\model\Product::where($where)->paginate(20);
}
function getTheme()
{
    return \think\facade\Config::get('theme', 'default');
}
function getThemePath()
{
    return getTheme() ? getTheme()['path'] : "";
}
function includeFile($path, $var = [])
{
//    return view("../../../template/" . getThemePath() . '/' . $path, $var)->send();
    return view($path, $var)->send();
}
function includeJs($path)
{
    return '<script src="'. assetPath() . $path . '" type="text/javascript" charset="utf-8"></script>';
}
function includeCss($path)
{
    return '<link rel="stylesheet" type="text/css" href="' . assetPath() . $path . '" />';
}
function imgSrc($path)
{
    return assetPath() . $path;
}
function assetPath()
{
    return '/asset/' . getThemePath() . '/';
}
function sysConf($key)
{
    $conf = \think\facade\Config::get('system');
    return $conf[$key];
}

// 错误跳转 同tp控制器方法 最后增加是否返回json
function showError($msg = '', $url = null, $data = '', $wait = 3, array $header = [], $return_json = false)
{
    if (is_null($url)) {
        $url = request()->isAjax() ? '' : 'javascript:history.back(-1);';
    } elseif ('' !== $url) {
        $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : url($url);
    }
    $result = [
        'code' => 0,
        'msg' => $msg,
        'data' => $data,
        'url' => $url,
        'wait' => $wait,
    ];
    if ($return_json == false) {
        $type = 'jump';
    }
    $response = \think\Response::create($result, $type)->header($header)->options(['jump_template' => config('dispatch_error_tmpl')]);
    throw new \think\exception\HttpResponseException($response);
}

/**
 * 操作成功跳转的快捷方法 同tp控制器方法 最后增加是否返回json
 */
function showSuccess($msg = '', $url = null, $data = '', $wait = 3, array $header = [], $return_json = false)
{
    if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) {
        $url = $_SERVER["HTTP_REFERER"];
    } elseif ('' !== $url) {
        $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : url($url);
    }
    $result = [
        'code' => 1,
        'msg' => $msg,
        'data' => $data,
        'url' => $url,
        'wait' => $wait,
    ];
    // 把跳转模板的渲染下沉，这样在 response_send 行为里通过getData()获得的数据是一致性的格式
    if ($return_json == false) {
        $type = 'jump';
    }
    $response = \think\Response::create($result, $type)->header($header)->options(['jump_template' => config('dispatch_success_tmpl')]);
    throw new \think\exception\HttpResponseException($response);
}

/**
 * 扩展系统函数
 * User: Ryan
 */

// 加密函数
function md500($str)
{
    return md5(sha1($str));
}

////整合数组，把子级整合到父级的_child里，形成树结构多维数组
//function unlimitedChild($list , $pid = 0 , $pid_name = "parent_id"){
//    $arr = [];
//    foreach ($list as $v) {
//        if($v[$pid_name] == $pid){
//            $v['_child'] = unlimitedChild($list , $v['id'] ,$pid_name);
//            $arr[] = $v;
//        }
//    }
//    return $arr;
//}
function now($only_date = false)
{
    return $only_date ? date('Y/m/d', time()) : date('Y/m/d H:i:s', time());
}

function formatDatetime($datetime, $date_format = "y/m/d", $time_format = ' H:i')
{
    $timeStamp = strtotime($datetime);
    $time = $time_format ? date($time_format, $timeStamp) : '';
    if (date('Ymd', time()) == date('Ymd', $timeStamp)) {
        $text = '今天' . $time;
    } elseif (date('Ymd', strtotime('yesterday')) == date('Ymd', $timeStamp)) {
        $text = '昨天' . $time;
    } elseif (date('Ymd', strtotime('tomorrow')) == date('Ymd', $timeStamp)) {
        $text = '明天' . $time;
    } else {
        $text = date($date_format, $timeStamp) . $time;
    }
    return $text;
}

/**
 * 字节转换
 */
function get_byte_size($size)
{
    $units = array(' B', ' KB', ' MB', ' GB', ' TB');
    for ($i = 0; $size > 1024; $i++) {
        $size /= 1024;
    }
    return round($size, 2) . $units[$i];
}

/**
 * textarea转换为html
 * @author TechLee
 */
function text_to_html($content, $type = '1')
{
    $str = '';
    switch ($type) {
        case '2':
            $str = '<p>' . str_replace(PHP_EOL, '</p><p>', $content) . '</p>';
            break;
        case '1':
        default:
            $str = str_replace(PHP_EOL, '<br>', $content);
            break;
    }
    return $str;
}

/**
 * xml对象转换为数组
 * @author TechLee
 */
function xml_to_array($xmlStr)
{
    $xmlObj = simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA);
    return json_decode(json_encode($xmlObj), true);
}

/**
 * 清除html标签
 * @author TechLee
 */
function clear_tags($str)
{
    $str = strip_tags($str);
    //首先去掉头尾空格
    $str = trim($str);
    $str = preg_replace("/(\s|\&nbsp\;|　|\xc2\xa0)/", "", strip_tags($str));
    //接着去掉两个空格以上的
    $str = preg_replace('/\s(?=\s)/', '', $str);
    //最后将非空格替换为一个空格
    $str = preg_replace('/[\n\r\t]/', ' ', $str);
    return $str;
}

/**
 * 清除html标签，字符串截取
 * 支持中文
 * @author TechLee
 */
function substr_cn($str, $length = 0, $start = 0, $charset = "utf-8", $suffix = true)
{
    $str = clear_tags($str);
    if (function_exists("mb_substr")) {
        if ($length > 0 && mb_strlen($str, $charset) <= $length) {
            return $str;
        }
        $slice = $length > 0 ? mb_substr($str, $start, $length, $charset) : $str;
    } else {
        $re['utf-8'] = "/[\x01-]|[�-�][�-�]|[�-�][�-�]{2}|[�-�][�-�]{3}/";
        $re['gb2312'] = "/[\x01-]|[�-�][�-�]/";
        $re['gbk'] = "/[\x01-]|[�-�][@-�]/";
        $re['big5'] = "/[\x01-]|[�-�]([@-~]|�-�])/";
        preg_match_all($re[$charset], $str, $match);
        if ($length > 0 && count($match[0]) <= $length) {
            return $str;
        }
        $slice = join("", $length > 0 ? array_slice($match[0], $start, $length) : $match[0]);
    }
    if ($suffix) {
        return $slice . "…";
    }
    return $slice;
}

function substrs($str, $length = 0, $start = 0)
{
    if ($length > 0 && strlen($str) <= $length) return $str;
    else
        return substr($str, 0, $length) . "...";
}

/**
 * openssl加密
 */
function do_encrypt($input)
{
    return base64_encode(openssl_encrypt(serialize($input), 'DES-ECB', '@19810618!ray', OPENSSL_RAW_DATA));
}

/**
 * openssl解密
 */
function do_decrypt($code)
{
    return unserialize(openssl_decrypt(base64_decode($code), 'DES-ECB', '@19810618!ray', OPENSSL_RAW_DATA));
}

/**
 * 无限极分类
 * 将数组转换为树形结构 的一维数组
 * @author TechLee
 */
function list2tree($dataList, $parent_id = 0, $depth = 0, $prefix = '|--')
{
    $resTree = [];
    foreach ($dataList as $key => $val) {
        if ($val['parent_id'] == $parent_id) {
            $val['depth'] = $depth;
            $val['prefix'] = str_repeat($prefix, $depth);
            unset($dataList[$key]);
            $resTree[] = $val;
            $resTree = array_merge($resTree, list2tree($dataList, $val['id'], $depth + 1));
        }
    }
    return $resTree;
}

/**
 * 把返回的数据集转换成子父类
 * @param $list
 * @param string $pk
 * @param string $pid
 * @param string $child
 * @param string $root
 * @return array
 */
function list2child($dataList, $root = '0', $pid = 'parent_id', $pk = 'id', $child = '_child')
{
    $tree = [];

    if (is_array($dataList)) {
        $refer = [];
        foreach ($dataList as $key => $data) {
            method_exists($data, 'toArray') and $dataList[$key] = $data->toArray();
        }
        foreach ($dataList as $key => $data) {
            $refer[$data[$pk]] = &$dataList[$key];
            $refer[$data[$pk]][$child] = [];
        }
        foreach ($dataList as $key => $data) {
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] = &$dataList[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent = &$refer[$parentId];
                    $parent[$child][] = &$dataList[$key];
                }
            }
        }
    }
    return $tree;
}

// 从数组里，递归查找上级分类，直到根分类的一维数组
function getParentsList($list, $cid, $parent_name = "parent_id")
{
    $arr = [];
    foreach ($list as $v) {
        if ($v['id'] == $cid) {
            $arr[] = $v;
            $arr = array_merge($arr, getParentsList($list, $v[$parent_name]));
        }
    }
    return $arr;
}

// 按一个作为父级分类的id查找其所有子类数据，不包含自己的一维数组
function getChildList($data, $cid, $parent_name = "parent_id")
{
    static $arr;
    foreach ($data as $v) {
        if ($v[$parent_name] == $cid) {
            $arr[] = $v;
            getChildList($data, $v['id']);
        }
    }
    return $arr;
}

/**
 * Curl请求，支持https，get，post，及非80,443端口。
 */
function url_request($data, $url = '', $method = 'post', $port = '80', $charset = 'utf-8')
{
    if (strstr($url, 'https://')) {
        $port = '443';
    }
    $form_data = "";
    if (is_array($data)) {
        foreach ($data as $key => $value) {
            if ($form_data == "") {
                $form_data = $key . "=" . rawurlencode($value);
            } else {
                $t = "&" . $key . '=' . rawurlencode($value);
                $form_data = $form_data . $t;
            }
        }
    } else {
        $form_data = $data;
    }

    $ch = curl_init();
    if (strtolower($charset) == 'gbk') {
        // header("Content-type:text/html;charset=gbk");
        $this_header = array("content-type: application/x-www-form-urlencoded;charset=gbk");
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this_header);
    }
    curl_setopt($ch, CURLOPT_PORT, $port);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false); //设定是否输出页面内容
    if ($port == '443') {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
    }
    if (strtolower($method) == 'post') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $form_data);
    } else {
        $url .= strstr($url, '?') ? '&' . $form_data : "?" . $form_data;
    }
    // echo $url;die;
    curl_setopt($ch, CURLOPT_URL, $url);
    // curl_setopt_array($ch, $option);
    $result = curl_exec($ch);
    // dump($result);
    return $result;
}

// 给结果集排序
function sortDataList($data, $field_name, $sort_type = 'asc')
{
    if ($sort_type == 'asc') {
        array_multisort(array_column($data, $field_name), SORT_ASC, $data);
    } else {
        array_multisort(array_column($data, $field_name), SORT_DESC, $data);
    }
    return $data;
}

//function getConfigByKey($key_name)
//{
//    return \think\Db::name('config')->where('key', $key_name)->cache(true)->value('value');
//}
function addImagePrefix($value)
{
    if ($value == null || strpos($value, 'http') !== false)
        $domain = '';
    else
        $domain = 'http://' . MAIN_DOMAIN;
    return $domain . str_replace('\\', '/', $value);
}

function removeImagePrefix($value)
{
    if ($value == false) return "";
    return strpos($value, MAIN_DOMAIN) ? substr($value, strpos($value, MAIN_DOMAIN) + strlen(MAIN_DOMAIN)) : $value;
}

//数字 转字母
function decimal2ABC($num)
{
    $num *= 1981;
    $ABCstr = "";
    $ten = $num;
    if ($ten == 0) return "A";
    while ($ten != 0) {
        $x = $ten % 26;
        $ABCstr .= chr(65 + $x);
        $ten = intval($ten / 26);
    }
    return strrev($ABCstr);
}

//字母（26）进制转10进制
function ABC2decimal($abc)
{
    $abc = strtoupper($abc); // 防止小写
    $ten = 0;
    $len = strlen($abc);
    for ($i = 1; $i <= $len; $i++) {
        $char = substr($abc, 0 - $i, 1);
        $int = ord($char);
        $ten += ($int - 65) * pow(26, $i - 1);
    }
    return $ten / 1981;
}

// 获取坐标的hash值  https://www.jianshu.com/p/02d12efc77ea  保留位数误差分别为： 4: 20km, 5: 2.4km  6: 0.61km 7: 0.076km
function getGeoHash($lat, $lng)
{
    $geohash = new \GeoHash\GeoHash();
    $geohash->setLatitude($lat);
    $geohash->setLongitude($lng);
    return $geohash->getHash();
//    return substr($geohash, 0, 4);
}

// 计算2个坐标之间的距离 默认是返回公里 否则返回 英里
function distance($lat1, $lng1, $lat2, $lng2, $miles = true)
{
    $pi80 = M_PI / 180;
    $lat1 *= $pi80;
    $lng1 *= $pi80;
    $lat2 *= $pi80;
    $lng2 *= $pi80;
    $r = 6372.797; // mean radius of Earth in km
    $dlat = $lat2 - $lat1;
    $dlng = $lng2 - $lng1;
    $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
    $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
    $km = $r * $c;
    return ($miles ? ($km * 0.621371192) : $km);
}

/**生成唯一码
 *   * @return string
 *   */
function makeSn()
{
    $code = "ABCDEFGHIGKLMNOPQRSTUVWXYZ";

    $rand = $code[rand(0, 25)]
        . strtoupper(dechex(date('m')))
        . date('d')
        . substr(time(), -6)
        . substr(microtime(), 2, 5)
        . sprintf('%02d', rand(0, 99));
    for (
        $a = md5($rand, true),
        $s = 'ABCDEFGHIJKLMNOPQRSTUV0123456789',
        $d = '',
        $f = 0;
        $f < 8;
        $g = ord($a[$f]), // ord（）函数获取首字母的 的 ASCII值
        $d .= $s[($g ^ ord($a[$f + 8])) - $g & 0x1F], //按位亦或，按位与。
        $f++
    ) ;
    return $d;
}

//// 通过状态值获得状态名
//function getStatusText($status_val,$status_name = '') {
//    if($status_name){
//        $conf = config('system.status.'.$status_name);
//        if(empty($conf)) return '未定义状态';
//        if(isset($conf[$status_val])) $text = $conf[$status_val];
//        else $text = $status_val;
//        return $status_val===null ? "" : $text;
//    }else{
//        return  $status_val==1 ? '正常' : "已禁用";
//    }
//}
// 通过状态名获得状态键
function getStatusValue($status_text, $status_name)
{
    $conf = config('status.' . $status_name);
    foreach ($conf as $k => $v) {
        if ($v === $status_text) {
            return $k;
        }
    }
    return null;
}

function get_client_ip($type = 0)
{
    $type = $type ? 1 : 0;
    static $ip = NULL;
    if ($ip !== NULL) return $ip[$type];
    if (isset($_SERVER['HTTP_X_REAL_IP'])) { //nginx 代理模式下，获取客户端真实IP
        $ip = $_SERVER['HTTP_X_REAL_IP'];
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { //客户端的ip
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { //浏览当前页面的用户计算机的网关
        $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos = array_search('unknown', $arr);
        if (false !== $pos) unset($arr[$pos]);
        $ip = trim($arr[0]);
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR']; //浏览当前页面的用户计算机的ip地址
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

// 以下用户选择题的存储
// 输入BD返回10 字母顺序无所谓
function answerChr2Num($chr)
{
    if (intval($chr) > 0) return 0;
    return array_sum(array_map(function ($i) {
        return pow(2, ord($i) - 65);
    }, str_split(strtoupper($chr))));
}

// 输入10返回BD
function fetchAnswerChr($num)
{
    $c = 0;
    $res = "";
    while ($num > 0) {
        if ($num & 1 == 1) {
            $res .= chr(65 + $c);
        }
        $num = $num >> 1;
        $c++;
    }
    return $res;
}

